
package com.closer.server.biz.user.validator;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.closer.server.biz.user.dto.SearchRequest;
import com.closer.server.biz.user.enums.UserRoleEnum;
import com.closer.server.mapper.user.UserMapper;
import com.closer.server.support.exception.ErrorCode;
import com.closer.server.support.exception.ThrowUtils;
import org.springframework.stereotype.Component;

@Component
public class UserValidator {

    private final UserMapper mapper;

    public UserValidator(UserMapper mapper) {
        this.mapper = mapper;
    }

    /**
     * 注册参数校验
     * @param account 账号
     * @param password 密码
     * @param checkPassword 确认密码
     */
    public void validate(String account, String password, String checkPassword) {
        ThrowUtils.throwIf(StrUtil.hasBlank(account, password, checkPassword), ErrorCode.PARAMS_ERROR,"参数为空");
        checkAccAndPwd(account, password);
        ThrowUtils.throwIf(!password.equals(checkPassword), ErrorCode.PARAMS_ERROR,"两次输入的密码不一致");
        ThrowUtils.throwIf(mapper.existByAccount(account) > 0, ErrorCode.OPERATION_ERROR, "账号已存在");
    }

    /**
     * 登录参数校验
     * @param account 账号
     * @param password 密码
     */
    public void validate(String account, String password) {
        ThrowUtils.throwIf(StrUtil.hasBlank(account, password), ErrorCode.PARAMS_ERROR,"参数为空");
        checkAccAndPwd(account, password);
        ThrowUtils.throwIf(mapper.existByAccount(account) <= 0, ErrorCode.OPERATION_ERROR, "账号不存在");
    }

    /**
     * 用户是否登录校验
     * @param userId 用户id
     */
    public void validate(Long userId) {
        ThrowUtils.throwIf(userId == null || userId <= 0, ErrorCode.PARAMS_ERROR,"参数错误");
        ThrowUtils.throwIf(!StpUtil.isLogin(), ErrorCode.OPERATION_ERROR,"用户未登录");
    }

    /**
     * 修改用户信息参数校验
     * @param userId 用户id
     * @param name 用户昵称
     * @param gender  性别
     * @param profile 简介
     * @param email 邮箱
     */
    public void validate(Long userId, String name, Integer gender, String profile, String email) {
        validate(userId); // 包含了 userId 合法性校验
        validateGender(gender);
        if (StrUtil.isNotBlank(name)) {
            ThrowUtils.throwIf(name.length() < 4 || name.length() > 30, ErrorCode.PARAMS_ERROR,"昵称长度4-30位");
            ThrowUtils.throwIf(!name.matches("^[a-zA-Z\u4e00-\u9fa50-9_]+$"), ErrorCode.PARAMS_ERROR, "昵称只能包含字母、中文、数字和下划线");
        }
        if (StrUtil.isNotBlank(profile)) {
            ThrowUtils.throwIf(profile.length() > 512, ErrorCode.PARAMS_ERROR,"简介长度不能超过512位");
        }
        if (StrUtil.isNotBlank(email)) {
            validateEmail(email);
        }
    }

    /**
     * 搜索用户参数校验
     * @param params 参数
     */
    public void validate(SearchRequest params) {
        if (params.getId() != null) {
            ThrowUtils.throwIf(params.getId() <= 0, ErrorCode.PARAMS_ERROR,"用户Id错误");
        }
        if (params.getAccount() != null) {
            checkAccount(params.getAccount());
        }
        if (params.getGender() != null) {
            validateGender(params.getGender());
        }
    }

    /**
     * 检查账号参数
     * @param account 账号
     */
    public void checkAccount(String account) {
        ThrowUtils.throwIf(account.length() < 4 || account.length() > 16, ErrorCode.PARAMS_ERROR,"账号长度4-16位");
        ThrowUtils.throwIf(!account.matches("^[a-zA-Z_]+$"), ErrorCode.PARAMS_ERROR, "账号只能包含字母、下划线");
    }

    /**
     * 检查密码参数
     * @param password 密码
     */
    public void checkPwd(String password) {
        ThrowUtils.throwIf(password.length() < 8, ErrorCode.PARAMS_ERROR,"密码长度至少8位");
        ThrowUtils.throwIf(!password.matches("^[a-zA-Z0-9_]+$"), ErrorCode.PARAMS_ERROR, "密码只能包含字母、数字和下划线");
    }

    /**
     * 修改用户信息参数校验（含角色）
     * @param userId 用户id
     * @param name 用户昵称
     * @param gender  性别
     * @param profile 简介
     * @param email 邮箱
     * @param role 角色
     */
    public void validate(Long userId, String name, Integer gender, String profile, String email, String role) {
        validate(userId, name, gender, profile, email);
        ThrowUtils.throwIf(UserRoleEnum.getEnumByValue(role) == null, ErrorCode.PARAMS_ERROR,"角色不存在");
    }

    public void checkAccAndPwd(String account, String password) {
        checkAccount(account);
        checkPwd(password);
    }
    private void validateGender(Integer gender) {
        ThrowUtils.throwIf(gender == null || gender < 0 || gender > 2, ErrorCode.PARAMS_ERROR,"性别错误");
    }

    private void validateEmail(String email) {
        ThrowUtils.throwIf(!email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"), ErrorCode.PARAMS_ERROR, "邮箱格式不正确");
    }
}